#include "StdAfx.h"

const char statekey[] = "amphetaminestate";
const int statekeylen = 16;

CState::CState()
{
fp = 0;
}

char *CState::MakeFilename(char *dest,int slot,char *fn)
{
if(slot == -1)
	sprintf(dest,"%s/%s.hi",settings.hidir,fn);
else if(slot == -2)
	sprintf(dest,"%s/%s.nvram",settings.nvramdir,fn);
else
	sprintf(dest,"%s/%s-%d.aState",settings.statedir,fn,slot);
return(dest);
}

int CState::Save(int s,char *fn)
{
char filename[1024];

MakeFilename(filename,s,fn);
Close();
if((fp = fopen(filename,"wb")) == 0)
	{
	message("CState::Save:  cant create/open save state file '%s'\n",filename); 
	return(1);
	}
message("CState::Save:  opened save state file '%s'\n",filename); 
return(0);
}

int CState::Load(int s,char *fn)
{
char filename[1024];

MakeFilename(filename,s,fn);
Close();
if((fp = fopen(filename,"rb")) == 0)
	{
	message("CState::Load:  cant open save state file '%s'\n",filename); 
	return(1);
	}
message("CState::Load:  opened save state file '%s'\n",filename); 
return(0);
}

int CState::Load(char *fn)
{
Close();
if((fp = fopen(fn,"rb")) == 0)
	{
	message("CState::Load:  cant open save state file '%s'\n",fn); 
	return(1);
	}
message("CState::Load:  opened save state file '%s'\n",fn); 
return(0);
}

void CState::Close()
{
if(fp)
	fclose(fp);
fp = 0;
}

u32 CState::FilePos()
{
return(ftell(fp));
}

void CState::WriteHeader(u8 ver)
{
Write((u8*)statekey,statekeylen);
Write8(ver);
}

void CState::Write(u8 *data,int len)
{
fwrite(data,len,1,fp);
}

void CState::Write8(u8 data)
{
fwrite(&data,sizeof(u8),1,fp);
}

void CState::Write16(u16 data)
{
fwrite(&data,sizeof(u16),1,fp);
}

void CState::Write32(u32 data)
{
fwrite(&data,sizeof(u32),1,fp);
}

void CState::Write64(u64 data)
{
fwrite(&data,sizeof(u64),1,fp);
}

u8 CState::ReadHeader()
{
char tmp[512];

Read((u8*)tmp,statekeylen);		//read key
if(strncmp(tmp,statekey,statekeylen) != 0)
	return(0xFF);						//error is returned
return(Read8());						//version is returned
}

int CState::Read(u8 *data,int len)
{
return((int)fread(data,len,1,fp));
}

u8 CState::Read8()
{
u8 ret;

fread(&ret,sizeof(u8),1,fp);
return(ret);
}

u16 CState::Read16()
{
u16 ret;

fread(&ret,sizeof(u16),1,fp);
return(ret);
}

u32 CState::Read32()
{
u32 ret;

fread(&ret,sizeof(u32),1,fp);
return(ret);
}

u64 CState::Read64()
{
u64 ret;

fread(&ret,sizeof(u64),1,fp);
return(ret);
}

/** CHighScore *****************************************/
CHighScore::CHighScore()
{
}

CHighScore::~CHighScore()
{
}

int CHighScore::Load(char *fn)
{
return(CState::Load(-1,fn));
}

int CHighScore::Save(char *fn)
{
return(CState::Save(-1,fn));
}

/** CNVRAM *********************************************/
CNVRAM::CNVRAM(char *n,u8 *p,u32 s)
{
SetData(n,p,s);
Load();				//fixme: i do not like loading in the constructor
}

CNVRAM::~CNVRAM()
{
Save();
}

int CNVRAM::Load()
{
if(Ptr && CState::Load(-2,Name) != 0)
	return(1);
Read(Ptr,Size);
Close();
message("nvram loaded\n");
return(0);
}

int CNVRAM::Save()
{
if(Ptr && CState::Save(-2,Name) != 0)
	return(1);
Write(Ptr,Size);
Close();
message("nvram saved\n");
return(0);
}

void CNVRAM::SetData(char *n,u8 *p,u32 s)
{
message("nvram inited\n");
strncpy(Name,n,32);
Ptr = p;
Size = s;
for(s=0;s<Size;s++)
	Ptr[s] = 0;
}
